//------------------------------------------------------------------------------------------------- 
// <copyright file="SetAvailableSiteTemplate.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Add / Remove a collection of SiteTemplates from the "Available SiteTemplates" List.
// </summary>

namespace Collaboris.Saf.Actions.Moss.Publishing
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    using Engine;

    using Entities;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Publishing;

    using SharePoint.Moss.Publishing;
    using SharePoint.Wss.Attributes;

    using Utils;

    [CollaborisClass(Title = "Set Available Site Templates", 
        ReleaseStatus = ReleaseStatus.Stable, 
        DisableDocumentation = false,
        ContactAuthorEmail = "Support@Collaboris.co.uk",
        Summary =
            "Adds or removes site templates from the 'Available Site Templates' collection in the current web.",
        UndoImplemented = true,
        ClassGuid = "{156E17A5-A7BA-4e1f-8A48-1BC341A7C619}")]
    public class SetAvailableSiteTemplates : MOSSActionBase<SiteTemplate>
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the SetAvailableSiteTemplates class.
        /// </summary>
        public SetAvailableSiteTemplates()
        {
            this.Scope = SPScope.Web;
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// This Action Adds the specified SiteTemplates to the Available SiteTemplates Collection.
        /// </summary>
        /// <param name="context">
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns>
        /// </returns>
        protected override ProcessStatus DoAction(SafContext context, SiteTemplate entity)
        {
            this.Trace.TraceMethodStart("DoAction");

            ValidationHelper.VerifyObjectArgument(context.Web, "context.Web");

            this.RunSetAvailableSiteTemplates(entity, context.Web, ProcessMode.Do);

            this.Trace.TraceMethodEnd("DoAction");

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Checks the Data entity for Validity
        /// </summary>
        /// <param name="context">The <see cref="IContext"/>context.</param>
        /// <param name="entity">The data entity to Validate</param>
        /// <param name="errors">List of <see cref="ProcessMode"/>s</param>
        /// <param name="mode"><see cref="ValidationError"/> signalling wheter we are Doing, or Undoing the action.</param>
        /// <returns>false if invalid</returns>
        protected override bool IsValid(
            SafContext context, SiteTemplate entity, ref List<ValidationError> errors, ProcessMode mode)
        {
            int currentCount = errors.Count;

            // Validate each object now.
            ValidateStringForNull(entity.Name, "SiteTemplate.SiteTemplateName", ref errors);

            if (!entity.LCID.HasValue)
            {
                entity.LCID = 1033;
            }

            // Have we added errors ?
            return errors.Count == currentCount;
        }

        /// <summary>
        /// Set the list of specified site templates as unavailable.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns><seealso cref="ProcessStatus"/></returns>
        protected override ProcessStatus UndoAction(SafContext context, SiteTemplate entity)
        {
            this.Trace.TraceMethodStart("UndoAction");

            ValidationHelper.VerifyObjectArgument(context.Web, "context.Web");

            this.RunSetAvailableSiteTemplates(entity, context.Web, ProcessMode.Undo);

            this.Trace.TraceMethodEnd("UndoAction");

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Sets the specified sitetemplates as available / unavailable based on the mode.
        /// </summary>
        /// <param name="entity">
        /// </param>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="mode">
        /// </param>
        private void RunSetAvailableSiteTemplates(SiteTemplate entity, SPWeb web, ProcessMode mode)
        {
            this.Trace.TraceMethodStart("RunSetAvailableSiteTemplates");

            web.AllowUnsafeUpdates = true;

            this.Trace.TraceVerbose("Getting the Publishing Site");
            PublishingWeb pubweb = PublishingWeb.GetPublishingWeb(web);
            ValidationHelper.VerifyObjectArgument(pubweb, "pubWeb");

            // Get the collection of SPWebTemplate.
            var webTemplateToWorkOn = new Collection<SPWebTemplate>();
            SPWebTemplate webTemplate = SiteTemplateHelper.GetSiteTemplate(pubweb, entity.Name, entity.LCID.Value);

            if (webTemplate != null)
            {
                webTemplateToWorkOn.Add(webTemplate);
            }

            // now lets use the site templates.
            if (webTemplateToWorkOn.Count > 0)
            {
                if (mode == ProcessMode.Do)
                {
                    this.Trace.TraceVerbose("Adding sitetemplate to the Available List.");
                    SiteTemplateHelper.SetAsAvailable(pubweb, webTemplateToWorkOn, entity.LCID.Value, true);
                }

                if (mode == ProcessMode.Undo)
                {
                    this.Trace.TraceVerbose("Removing sitetemplate from the Available List.");
                    SiteTemplateHelper.SetAsUnAvailable(pubweb, webTemplateToWorkOn, entity.LCID.Value, true);
                }
            }

            this.Trace.TraceMethodEnd("RunSetAvailableSiteTemplates");
        }

        #endregion
    }
}